package com.shaw.client.mvc.widgt;
import com.extjs.gxt.ui.client.core.XDOM;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.FormEvent;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.impl.FormPanelImpl;



public class FixedFormPanel extends FormPanel {

	@Override
	protected void onAttach() {
		super.onAttach();
		Element iFrame = getIFrameElement();
		Element fixedIFrame = createFixedFrame();

		FormPanelImpl impl = getImpl();
		impl.unhookEvents(iFrame, getLayoutTarget().dom);
		XDOM.getBody().removeChild(iFrame);

		XDOM.getBody().appendChild(fixedIFrame);
		impl.hookEvents(fixedIFrame, getLayoutTarget().dom, this);

		setIFrameElement(fixedIFrame);
	}

	private Element createFixedFrame() {
		Element dummy = DOM.createDiv();
		DOM.setInnerHTML(dummy, "<iframe src=\"javascript:''\" name='"
				+ getFrameName()
				+ "' style='position:absolute;width:0;height:0;border:0'>");

		return DOM.getFirstChild(dummy);
	}

	@Override
	public void onFrameLoad() {
		UncaughtExceptionHandler handler = GWT.getUncaughtExceptionHandler();
		if (handler != null) {
			onFrameLoadAndCatch(handler);
		} else {
			onFrameLoadImpl();
		}
	}

	private void onFrameLoadImpl() {
		DeferredCommand.addCommand(new Command() {
			public void execute() {
				fireEvent(Events.Submit, new FormEvent(FixedFormPanel.this,
						getContents(getIFrameElement())));
			}
		});
	}

	private native String getFrameName() /*-{
		return this.@com.extjs.gxt.ui.client.widget.form.FormPanel::frameName;
	}-*/;

	private native Element getIFrameElement() /*-{
		return this.@com.extjs.gxt.ui.client.widget.form.FormPanel::iframe;
	}-*/;

	private native void setIFrameElement(Element fixedIFrame) /*-{
		this.@com.extjs.gxt.ui.client.widget.form.FormPanel::iframe = fixedIFrame;
	}-*/;

	private native FormPanelImpl getImpl() /*-{
		return @com.extjs.gxt.ui.client.widget.form.FormPanel::impl;
	}-*/;

	public native String getContents(Element iframe) /*-{
		try {
		  // Make sure the iframe's window & document are loaded.
		  if (!iframe.contentWindow ||!iframe.contentWindow.document)
		    return "NULL";

		  // Get the body's entire inner HTML.
		  return iframe.contentWindow.document.documentElement.innerHTML ;//iframe.contentWindow.document.innerHTML;
		} catch (e) {
		  return "kwkw";
		}
	}-*/;

	private void onFrameLoadAndCatch(UncaughtExceptionHandler handler) {
		try {
			onFrameLoadImpl();
		} catch (Throwable e) {
			handler.onUncaughtException(e);
		}
	}

}
